﻿using System;
using System.Runtime.Serialization;
using JTLeigh.Commerce.Spencer.Core.Common;

namespace JTLeigh.Commerce.Spencer.Core.Service.Contracts
{

    /// <summary>
    /// Data contract representing a fully-qualified product identifier, including both the catalog
    /// identifier and the product identifier.
    /// </summary>
    [DataContract(Name = "FullyQualifiedProductId", Namespace = "http://schemas.jtleigh.com/Commerce/Spencer/Core/1.0/")]
    public class FullyQualifiedProductId
    {

        #region Properties

        /// <summary>
        /// Gets or sets the catalog identifier <see cref="String"/> of the catalog that the product is in.
        /// </summary>
        [DataMember(Name = "CatalogId", IsRequired = true)]
        public string CatalogId { get; set; }

        /// <summary>
        /// Gets or sets the product identifier <see cref="String"/> of the product.
        /// </summary>
        [DataMember(Name = "ProductId", IsRequired = true)]
        public string ProductId { get; set; }

        #endregion // Properties

        #region Methods

        /// <summary>
        /// Compares this object and the specified object for equality.
        /// </summary>
        /// <param name="obj">The <see cref="object"/> to compare.</param>
        /// <returns><see langword="true"/> if the two objects are equal, <see langword="false"/>
        /// otherwise.</returns>
        /// <remarks>
        /// <para>
        /// The two objects will be equal if both are <see cref="FullyQualifiedProductId"/> and if
        /// both their <see cref="FullyQualifiedProductId.CatalogId"/> and <see cref="FullyQualifiedProductId.ProductId"/>
        /// properties are equal.
        /// </para>
        /// </remarks>
        public override bool Equals(object obj)
        {
            FullyQualifiedProductId product;

            if (obj == null)
            {
                return false;
            }

            if (obj == this)
            {
                return true;
            }

            product = obj as FullyQualifiedProductId;
            if (product == null)
            {
                return false;
            }

            Safety.AssertNotNull(CatalogId, "FullyQualifiedProductId.CatalogId must not be null.");
            Safety.AssertNotNull(ProductId, "FullyQualifiedProductId.ProductId must not be null.");

            if (!CatalogId.Equals(product.CatalogId))
            {
                return false;
            }

            if (!ProductId.Equals(product.ProductId))
            {
                return false;
            }

            return true;
        }

        /// <summary>
        /// Gets the hash code for this object.
        /// </summary>
        /// <returns>The hash code.</returns>
        public override int GetHashCode()
        {
            int hashCode;

            Safety.AssertNotNull(CatalogId, "FullyQualifiedProductId.CatalogId must not be null.");
            Safety.AssertNotNull(ProductId, "FullyQualifiedProductId.ProductId must not be null.");

            hashCode = 0;
            hashCode = (hashCode * 397) ^ CatalogId.GetHashCode();
            hashCode = (hashCode * 397) ^ ProductId.GetHashCode();

            return hashCode;
        }

        #endregion // Methods

    }

}
